package io.yizoo.business.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import io.elm.core.CoreController;
import io.minio.GetObjectArgs;
import io.yizoo.business.entity.*;
import io.yizoo.system.entity.sys_file;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


@RestController
@RequestMapping("/business/hrm/salary")
public class hrm_salaryController extends CoreController {

    private static final String TEMPLATE_NAME = "/template/salary_template.xlsx";
    @Override
    protected void Init() {
        PowerEntity = biz_hrm_salary.class;
        PowerUse = EnumSet.of(Power.IDDelete, Power.IDAny, Power.IDGetSingle,Power.IDUpsert);
    }

    //更新或新增工资数据
    @PostMapping("/UpsertSalary")
    public Object UpsertSalary(@RequestBody String jsonStr) {
        String id = Ctor.HMapper.Upsert(biz_hrm_salary.class, jsonStr);
        return JsonResult(id != null ? 1 : 0);
    }
    @PostMapping("/GetList")
    public Object GetCostData(@RequestBody String jsonStr) {
        List<?> ret = Ctor.CoreMapper.USelect(
                Ctor.DMaker(jsonStr).Selector
                        .From(biz_hrm_salary.class,"a")
                        .Select("a.*,b.name as uname")
                        .LeftJoin(biz_hrm_ei_basic.class,"b", "a.emp_code = b.emp_code")
                        .IsWhere("and a.emp_code = #{emp_code}","emp_code")
                        .IsWhere("and a.month = #{month}","month")
                        .IsWhere("and a.year = #{year}","year")
                        .OrderBy("create_date")
                        .IsPage()
                        .GetFactor());

        return JsonResultPage(ret);
    }
    @GetMapping("/ExportSalary")
    public void ExportSalary(HttpServletResponse response) {
        try ( InputStream inputStream = getInputStream(TEMPLATE_NAME);
              ServletOutputStream outputStream = response.getOutputStream();
                Workbook workbook = new XSSFWorkbook(inputStream);){

            Sheet sheet = workbook.getSheetAt(0);
            Row row = sheet.getRow(1);
            for (Cell cell : row) {
                cell.setCellValue("");
            }
            String fileName = "薪酬管理模板.xlsx";
            fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-Disposition", "attachment; filename="+fileName);
            workbook.write(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("模板解析失败！");
            throw new RuntimeException(e);
        }

    }
    @PostMapping("/ImportSalary")
    public Object ImportSalary(@RequestBody String jsonStr) {
        sys_file mod = Ctor.HMapper.GetSingle(sys_file.class,
                Ctor.DMaker(jsonStr).Selector
                        .From(sys_file.class)
                        .Where("and rel_id=#{rel_id}","rel_id")
                        .Where("and module_name=#{module_name}","module_name")
                        .GetFactor()
        );

        InputStream inputStream = null;
        try {
            inputStream = Ctor.Minior.minioClient().getObject((GetObjectArgs)((GetObjectArgs.Builder)((GetObjectArgs.Builder)GetObjectArgs.builder().bucket("yizoo")).object(mod.getMiniio_name())).build());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        if (inputStream == null) {
            System.out.println("文件不存在请重新上传 dto: "+ jsonStr);
            throw new RuntimeException("文件不存在请重新上传");

        }

            try {
                List<Map<String, Object>> results = new ArrayList<>();
                Set<String> nameList = new HashSet<>();
                Workbook workbook = new XSSFWorkbook(inputStream);
                Map<Integer, String> colKeyMap = getColKeyMap();
                // 获取第一个表单
                    Sheet sheet = workbook.getSheetAt(0);
                for (Row row : sheet) {
                    Map<String,Object> dataMap = new HashMap<>();
                    if (row.getRowNum() == 0) {
                        continue;
                    }
                    for (Cell cell : row) {
                        String key = colKeyMap.get(cell.getColumnIndex());
                        if ("uname".equals(key)) {
                            if (StringUtils.isEmpty(cell.getStringCellValue())) {
                                continue;
                            }
                            nameList.add(cell.getStringCellValue());
                        }
                        switch (cell.getCellType()) {
                            case STRING:
                                dataMap.put(key,cell.getStringCellValue());
                                break;
                            case NUMERIC:
                                if (DateUtil.isCellDateFormatted(cell)) {
                                    dataMap.put(key,cell.getDateCellValue());
                                } else {
                                    dataMap.put(key,cell.getNumericCellValue());
                                }
                                break;

                        }

                    }
                    if (dataMap.size()>0) {
                        results.add(dataMap);
                    }
                }

                List<Object> retList = new ArrayList<>();
                for (String s : nameList) {
                    List<?> ret = Ctor.CoreMapper.USelect(
                            Ctor.DMaker()
                                    .Selector
                                    .putFactorItem("name",s)
                                    .From(biz_hrm_ei_basic.class)
                                    .IsWhere("and name like concat('%', #{name}, '%')", "name")
                                    .GetFactor());
                    if (!CollectionUtils.isEmpty(ret)) {

                        retList.add(ret.get(0));
                    }
                }

                Map<String,String> nameMap = new HashMap<>();
                for (Object o : retList) {
                    if (o instanceof Map) {
                        biz_hrm_ei_basic biz_hrm_ei_basic = JSONObject.parseObject(JSON.toJSONString(o), biz_hrm_ei_basic.class);
                   // biz_hrm_ei_basic biz_hrm_ei_basic = (biz_hrm_ei_basic) o;
                        nameMap.put(biz_hrm_ei_basic.getName(),biz_hrm_ei_basic.getEmp_code());
                    }
                }
                Set<String> empCodeSet = new HashSet<>();
                Set<String> monthSet = new HashSet<>();
                for (Map<String, Object> result : results) {
                    String uname = (String)result.get("uname");
                    if (StringUtils.isEmpty(uname)) {
                        result.remove("uname");
                        continue;
                    }
                        String month = result.get("month").toString();
                    if (!StringUtils.isEmpty(month)) {
                        monthSet.add(month.replace(".0",""));
                    }
                    String emp_code = nameMap.get(uname);
                    result.put("emp_code",emp_code);
                    result.remove("uname");
                    if (emp_code == null) {
                        continue;
                    }
                    empCodeSet.add(emp_code);

                }
                List<biz_hrm_salary> biz_hrm_salaryList = new ArrayList<>();
                for (Map<String, Object> result : results) {
                    String jsonString = JSON.toJSONString(result);
                    biz_hrm_salary biz_hrm_salary = JSON.parseObject(jsonString, new TypeReference<biz_hrm_salary>() {
                    });
                    biz_hrm_salary.setCreate_date(new Date());
                    biz_hrm_salary.setCreate_user("admin");
                    biz_hrm_salary.setStatus("1");
                    biz_hrm_salaryList.add(biz_hrm_salary);
                }
                StringJoiner empCodeStr = new StringJoiner(",","","");
                for (String s : empCodeSet) {
                    if (StringUtils.isEmpty(s)) {
                        continue;
                    }
                    empCodeStr.add("'"+s+"'");
                }
                StringJoiner monthStr = new StringJoiner(",","","");
                for (String s : monthSet) {
                    if (StringUtils.isEmpty(s)) {
                        continue;
                    }
                    monthStr.add("'"+s+"'");
                }
                Ctor.CoreMapper.UDelete(this.Ctor.DMaker().
                        Deleter.From(biz_hrm_salary.class)
                        .Where("and emp_code in ("+ empCodeStr.toString()+") and month in ("+monthStr.toString()+")")
                        .GetFactor());
                int save = this.Ctor.HMapper.Save(biz_hrm_salaryList,this.Ctor.DMaker().Deleter.From(biz_hrm_salary.class).Where("and emp_code in ("+ empCodeStr.toString()+") and month in ("+monthStr.toString()+")").GetFactor());
                workbook.close();
            } catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            } finally {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return JsonResult(1);


    }

    public static void main(String[] args) {
        StringJoiner stringJoiner = new StringJoiner(",","","");

        for (int i = 0; i < 10; i++) {
            stringJoiner.add("'"+i+"'");
        }
//        for (String s : nameList) {
//            stringJoiner.add("'"+s+"',");
//        }
        System.out.println(stringJoiner.toString());
    }

    private Map<Integer, String> getColKeyMap() {
        InputStream inputStream1 = getInputStream(TEMPLATE_NAME);
            Map<Integer, String> colKeyMap = new HashMap<>();
        Workbook workbook = null;
        try {
            workbook = new XSSFWorkbook(inputStream1);
            Sheet sheet = workbook.getSheetAt(0);
            Row row = sheet.getRow(1);
            for (Cell cell : row) {
                colKeyMap.put(cell.getColumnIndex(), extractVariableName(cell.getStringCellValue()));
            }

        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("模板解析失败！");
            throw new RuntimeException(e);
        } finally {
            try {
                inputStream1.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                workbook.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return colKeyMap;

    }
    /**
     * 从形如 "${variableName}" 的字符串中提取变量名。
     *
     * @param input 输入的字符串，例如 "${a}"
     * @return 提取出的变量名，例如 "a"；如果输入格式不正确，则返回 null
     */
    public static String extractVariableName(String input) {
        // 正则表达式匹配 "${...}" 格式的字符串
        String regex = "\\$\\{([a-zA-Z_][a-zA-Z0-9_]*)\\}";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(input);

        if (matcher.find()) {
            // 如果找到了匹配的部分，则返回第一个捕获组（即变量名）
            return matcher.group(1);
        } else {
            // 如果没有找到匹配的部分，则返回 null 或者可以根据需要抛出异常
            return null;
        }
    }

    private InputStream getInputStream(String fileName) {
        InputStream inputStream = null;
        try {
            inputStream = hrm_salaryController.class.getResourceAsStream(fileName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return inputStream;
    }

}
